package name.sakanacatcher.service;

import com.alibaba.fastjson.JSONObject;
import name.sakanacatcher.entity.*;
import name.sakanacatcher.repository.GroupRepository;
import name.sakanacatcher.repository.MessageRepository;
import name.sakanacatcher.repository.UnReadRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;

@Service
public class InformService {
    @Autowired
    GroupRepository groupRepository;

    @Autowired
    UserService userService;

    @Autowired
    ComService comService;

    @Autowired
    UnReadRepository unReadRepository;

    @Autowired
    MessageRepository messageRepository;

    public GroupRepository getGroupRepository() {
        return groupRepository;
    }

    public MessageRepository getMessageRepository() {
        return messageRepository;
    }

    public UserService getUserService() {
        return userService;
    }

    public UnReadRepository getUnReadRepository() {
        return unReadRepository;
    }


    @Transactional
    public Group getP2PGroupByName(String name){
        List<String> users = Arrays.asList(name.split("_"));
        users = new ArrayList<String>(new TreeSet<String>(users));
        if(getGroupRepository().getGroupByName(name) == null){
            List<User> userList = new ArrayList<>();
            for(String uid:users){
                User user = userService.getUserRepository().getById(Integer.parseInt(uid));
                userList.add(user);
            }
            Group group = new Group(name,"p2p",userList);
            return groupRepository.save(group);
        }
        else {
            return getGroupRepository().getGroupByName(name);
        }
    }

    @Transactional
    public void cleanUnRead(int uid, int gid){
        UnRead unRead = unReadRepository.getUnReadByUserIdAndMessageGroupId(uid,gid);
        if (unRead != null){
            unRead.setNum(0);
            unReadRepository.save(unRead);
        }

    }


    public List<UnRead> getAllP2PUnReadByUid(int uid){
        List<UnRead> unReadList = unReadRepository.getAllByUserId(uid);
        unReadList.sort(new Comparator<UnRead>() {
            @Override
            public int compare(UnRead unRead, UnRead t1) {
                return (int) (unRead.getMessage().getCreateTime().getTime() - t1.getMessage().getCreateTime().getTime());
            }
        });
        return unReadList;
    }



    public List<Message> getAllMessageByGroupName(String name) {
        List<Message> messages = messageRepository.getAllByGroupName(name);
        messages.sort(new Comparator<Message>() {
            @Override
            public int compare(Message message, Message t1) {
                return (int) (t1.getCreateTime().getTime() - message.getCreateTime().getTime());
            }
        });
        return messages;
    }


    @Transactional
    public int sendMessage(Map<String, Object> data){
        Group group = groupRepository.getGroupByName((String)data.get("groupName"));
        Message message = parseMap(data);
        message = messageRepository.save(message);
        groupRepository.save(group);
        return message.getId();
    }

    @Transactional
    public int sendMessage(JSONObject data){
        Group group = groupRepository.getGroupByName((String)data.get("groupName"));
        Message message = parseJSON(data);
        message = messageRepository.save(message);
        for(User user:group.getUsers()){
            UnRead unRead;
            if(unReadRepository.existsUnReadByUserIdAndMessageGroupId(user.getId(),message.getGroup().getId())) {
                unRead = unReadRepository.getUnReadByUserIdAndMessageId(user.getId(), message.getGroup().getId());
                unRead.setMessage(message);
            }
            else
                unRead = unReadRepository.save(new UnRead(userService.getUserRepository().getById(user.getId()),message));

            if(message.getSender().getUsername().equals(user.getUsername())){
                unRead.setNum(0);
            } else {
                unRead.setNum(unRead.getNum() + 1);
            }
            unReadRepository.save(unRead);
        }
        groupRepository.save(group);
        return message.getId();
    }

    public Message parseMap(Map<String, Object> data){
        return new Message(
            userService.getUserRepository().getById((int)data.get("senderId")),
            groupRepository.getGroupByName((String) data.get("groupName")),
            (String) data.get("content"),
            "dialog",
            new Date()
        );
    }

    public Message parseJSON(JSONObject data){
        return new Message(
                userService.getUserRepository().getById((int)data.get("senderId")),
                groupRepository.getGroupByName((String) data.get("groupName")),
                (String) data.get("content"),
                "dialog",
                new Date()
        );
    }
}
